home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / Tools / freeWAIS-sf-1.1 / ui / source.c < prev    next >
C/C++ Source or Header  |  1994-09-06  |  21KB  |  883 lines

  1. /* 
  2.   WIDE AREA INFORMATION SERVER SOFTWARE:
  3.    No guarantees or restrictions.  See the readme file for the full standard
  4.    disclaimer.
  5.  
  6.    This is part of the shell user-interface tools for the WAIS software.
  7.    Do with it as you please.
  8.  
  9.    jonathan@Think.COM
  10. */
  11.  
  12. /* Copyright (c) CNIDR (see ../COPYRIGHT) */
  13.  
  14. /*
  15.  * $Log: source.c,v $
  16.  * Revision 1.7  1994/08/22  14:13:31  pfeifer
  17.  * jp made the getenv code safer
  18.  *
  19.  * Revision 1.7  1994/08/22  14:13:31  pfeifer
  20.  * jp made the getenv code safer
  21.  *
  22.  * Revision 1.6  1994/08/15  16:17:05  pfeifer
  23.  * fixed uncheckt usage of getenv("USER") in printf
  24.  *
  25.  * Revision 1.5  1994/08/05  07:30:16  pfeifer
  26.  * Release beta 04
  27.  *
  28.  * Revision 1.4  93/07/02  19:27:26  warnock
  29.  * fix call to getdomainname from mike@tab00.larc.nasa.gov
  30.  * 
  31.  * Revision 1.3  93/07/01  19:21:26  warnock
  32.  * gethostname -> mygethostname
  33.  * 
  34.  * Revision 1.2  93/06/23  20:06:03  warnock
  35.  * Removed FORWARDER_SERVER pointer to Francois
  36.  * 
  37.  * Revision 1.1  93/06/23  20:02:20  warnock
  38.  * Initial revision
  39.  * 
  40.  * Revision 1.1  1993/02/16  15:09:27  freewais
  41.  * Initial revision
  42.  *
  43.  * Revision 1.16  92/04/02  14:22:23  jonathan
  44.  * Added sopysourceID.
  45.  * 
  46.  * Revision 1.15  92/04/01  17:18:39  jonathan
  47.  * Added FORWARDER_SERVER stuff.
  48.  * 
  49.  * Revision 1.14  92/03/17  14:39:55  jonathan
  50.  * Cleaned up.
  51.  * 
  52.  * Revision 1.13  92/03/06  14:50:53  jonathan
  53.  * New and Improved source loading!
  54.  * 
  55.  * Revision 1.12  92/03/05  11:47:30  jonathan
  56.  * Replaced directory routines with scandir's.
  57.  * 
  58.  * Revision 1.11  92/03/04  19:21:11  jonathan
  59.  * Handle EOF on read of source.  This fixes looping when source description
  60.  * is broken.
  61.  * 
  62.  * Revision 1.10  92/03/04  18:45:17  jonathan
  63.  * Modified WriteSource to use WriteString for description.
  64.  * 
  65.  * Revision 1.9  92/03/01  13:53:30  jonathan
  66.  * Added routines for X interface in effort to combine x/source.c and
  67.  * ui/source.c
  68.  * 
  69.  * Revision 1.8  92/03/01  13:07:25  jonathan
  70.  * Added check of s->thisSource to avoid errors when there are no sources.
  71.  * 
  72.  */
  73.  
  74. #ifndef lint
  75. static char *RCSid = "$Header: /usr/local/ls6/src+data/src/freeWAIS-sf/ui/RCS/source.c,v 1.7 1994/08/22 14:13:31 pfeifer Exp $";
  76. #endif
  77.  
  78. #define _C_SOURCE
  79. /* (jp) */
  80. #define EXTERN_SOURCE_ITEMS
  81. #define EXTERN_SOURCE_PATH
  82.  
  83. #include "wais.h"
  84. #include "globals.h"
  85.  
  86. #define DESC_SIZE 65535
  87.  
  88. /*
  89. #if defined(BSD) || defined(BSD43)
  90. #include <strings.h>
  91. #define strchr index
  92. #endif
  93. */
  94. #include "../ir/cdialect.h"
  95. extern int alphasort();
  96.  
  97. void
  98. freeSourceID(sid)
  99. SourceID sid;
  100. {
  101.   if (sid != NULL) {
  102.     if (sid->filename != NULL) s_free(sid->filename);
  103.     s_free(sid);
  104.   }
  105. }
  106.  
  107. SourceID
  108. copysourceID(sid)
  109. SourceID sid;
  110. {
  111.   SourceID result = NULL;
  112.   if(sid != NULL) {
  113.     if((result = (SourceID) s_malloc(sizeof(_SourceID))) != NULL) {
  114.       result->filename = s_strdup(sid->filename);
  115.     }
  116.   }
  117.   return result;
  118. }
  119.  
  120. char **
  121. buildSourceItemList(sourcelist)
  122. SourceList sourcelist;
  123. {
  124.   char **result;
  125.   int num, i;
  126.   SourceList source;
  127.  
  128.   /* find the length of the sidlist in the question */
  129.  
  130.   for(num = 0, source = sourcelist; 
  131.       source != NULL && source->thisSource != NULL;
  132.       num++, source = source->nextSource);
  133.  
  134.   result = (char**)s_malloc((1+num)*sizeof(char*));
  135.   if(num > 0)
  136.     for(i =0, source = sourcelist; i<num; i++, source = source->nextSource)
  137.       result[i] = source->thisSource->filename;
  138.   result[num] = NULL;
  139.   return(result);
  140. }
  141.  
  142. char **
  143. buildSItemList(sourcelist)
  144. SList sourcelist;
  145. {
  146.   char **result;
  147.   int num, i;
  148.   SList source;
  149.  
  150.   /* find the length of the sidlist in the question */
  151.  
  152.   for(num = 0, source = sourcelist; 
  153.       source != NULL;
  154.       num++, source = source->nextSource);
  155.  
  156.   result = (char**) s_malloc((1+num)*sizeof(char*));
  157.   if(num > 0)
  158.     for(i =0, source = sourcelist; i<num; i++, source = source->nextSource)
  159.       if(source->thisSource != NULL)
  160.     result[i] = source->thisSource->name;
  161.   result[num] = NULL;
  162.   return(result);
  163. }
  164.  
  165. short
  166. ReadSourceID(file, sid)
  167. FILE *file;
  168. SourceID sid;
  169. {
  170.   char temp_string[MAX_SYMBOL_SIZE];
  171.   char filename[MAX_SYMBOL_SIZE];
  172.   short check_result;
  173.  
  174.   check_result = CheckStartOfStruct("source-id", file);
  175.   filename[0] = '\0';
  176.   if(FALSE == check_result){ 
  177.     return(false);
  178.   }
  179.   if(END_OF_STRUCT_OR_LIST == check_result)
  180.     {
  181.       return(FALSE);
  182.     }
  183.     
  184.   /* read the slots: */
  185.   while(TRUE){
  186.  
  187.     short check_result = ReadSymbol(temp_string, file, MAX_SYMBOL_SIZE);
  188.     if(END_OF_STRUCT_OR_LIST == check_result) break;
  189.     if(FALSE == check_result){
  190.       return(false);
  191.     } 
  192.     if(0 == strcmp(temp_string, ":filename")) {
  193.       if (FALSE == ReadString(filename, file, MAX_SYMBOL_SIZE))
  194.     return(false);
  195.       sid->filename = s_strdup(filename);
  196.     }
  197.     else
  198.       SkipObject(file);
  199.   }
  200.   return(TRUE);
  201. }
  202.  
  203. SourceList ReadListOfSources(file)
  204. FILE *file;
  205. {
  206.   short check_result;
  207.   SourceID sid = NULL;
  208.   SourceList result, this, last;
  209.           
  210.   /* initialize */
  211.   this = last = result = NULL;
  212.  
  213.   if(ReadStartOfList(file) == FALSE)
  214.     return(NULL);
  215.  
  216.   while(TRUE) {
  217.     sid = (SourceID)s_malloc(sizeof(_SourceID));
  218.     check_result = ReadSourceID(file, sid);
  219.     if(check_result == END_OF_STRUCT_OR_LIST) {
  220.       s_free(sid);
  221.       return(result);
  222.     }
  223.     else if(check_result == FALSE)
  224.       return(result);
  225.  
  226.     else if(check_result == TRUE) {
  227.       if(result == NULL)
  228.     result = this = (SourceList)s_malloc(sizeof(_SourceList));
  229.       else
  230.     this = (SourceList)s_malloc(sizeof(_SourceList));
  231.       this->thisSource = sid;
  232.       if(last != NULL)
  233.     last->nextSource = this;
  234.       last = this;
  235.     }
  236.   }
  237. }
  238.  
  239. Boolean ReadSource(source, file)
  240. Source source;
  241. FILE *file;
  242. {
  243.   char temp_string[MAX_SYMBOL_SIZE];
  244.   char desc_string[DESC_SIZE];
  245.   short check_result;
  246.   long port;
  247.  
  248.   long version;
  249.  
  250.   /* make sure it's a Source */
  251.   
  252.   check_result = CheckStartOfStruct("source", file);
  253.   if(FALSE == check_result){ 
  254.     return(false);
  255.   }
  256.   if(END_OF_STRUCT_OR_LIST == check_result)
  257.     {
  258.       return(FALSE);
  259.     }
  260.     
  261.   strcpy(source->server, "");
  262.   strcpy(source->service, "");
  263.  
  264.   /* read the slots: */
  265.   while(TRUE){
  266.  
  267.     short check_result = ReadSymbol(temp_string, file, MAX_SYMBOL_SIZE);
  268.     if((END_OF_STRUCT_OR_LIST == check_result)  || 
  269.        (EOF == check_result))
  270.       break;
  271.     if(FALSE == check_result){
  272.       return(false);
  273.     } 
  274.     if(0 == strcmp(temp_string, ":version")) {
  275.       if(FALSE == ReadLong(file, &version))
  276.     return(false);
  277.     }
  278.     else if(0 == strcmp(temp_string, ":ip-name")) {
  279.       if(FALSE == ReadString(temp_string, file, MAX_SYMBOL_SIZE))
  280.     return(false);
  281.       strcpy(source->server, temp_string);
  282.     }
  283.     else if(0 == strcmp(temp_string, ":ip-address")) {
  284.       if(FALSE == ReadString(temp_string, file, MAX_SYMBOL_SIZE))
  285.     return(false);
  286.       strcpy(source->server, temp_string);
  287.     }
  288.     else if(0 == strcmp(temp_string, ":configuration")) {
  289.       if(FALSE == ReadString(temp_string, file, MAX_SYMBOL_SIZE))
  290.     return(false);
  291.       find_value(temp_string, "IPAddress", source->server, STRINGSIZE);
  292.       find_value(temp_string, "RemotePort", source->service, STRINGSIZE);
  293.     }
  294.     else if(0 == strcmp(temp_string, ":tcp-port")) {
  295.       if(FALSE == ReadLong(file, &port))
  296.     return(false);
  297.       sprintf(source->service,"%d", port);
  298.     }
  299.     else if(0 == strcmp(temp_string, ":port")) {
  300.       if(FALSE == ReadLong(file, &port))
  301.     return(false);
  302.       sprintf(source->service,"%d", port);
  303.     }
  304.     else if(0 == strcmp(temp_string, ":maintainer")) {
  305.       if(FALSE == ReadString(temp_string, file, MAX_SYMBOL_SIZE))
  306.     return(false);
  307.       if(source->maintainer != NULL) s_free(source->maintainer);
  308.       source->maintainer = s_strdup(temp_string);
  309.     }
  310.     else if(0 == strcmp(temp_string, ":database-name")) {
  311.       if(FALSE == ReadString(temp_string, file, MAX_SYMBOL_SIZE))
  312.     return(false);
  313.       strcpy(source->database, temp_string);
  314.     }
  315.     else if(0 == strcmp(temp_string, ":cost")) {
  316.       double cost;
  317.       if(FALSE == ReadDouble(file, &cost))
  318.     return(false);
  319.       sprintf(source->cost, "%.2f", cost);
  320.     }
  321.     else if(0 == strcmp(temp_string, ":cost-unit")) {
  322.       if(FALSE == ReadSymbol(temp_string, file, MAX_SYMBOL_SIZE))
  323.     return(false);
  324.       strcpy(source->units, temp_string);
  325.     }
  326.     else if(0 == strcmp(temp_string, ":description")) {
  327.       if(FALSE == ReadString(desc_string, file, DESC_SIZE))
  328.     return(false);
  329.       if(source->description != NULL) s_free(source->description);
  330.       source->description = s_strdup(desc_string);
  331.     }
  332.     else if(0 == strcmp(temp_string, ":update-time")) {
  333.       if(EOF == SkipObject(file)) break;
  334.     }
  335.     else
  336.       if(EOF == SkipObject(file)) break; /* we don't know the key, so we don't know how
  337.                to interpret the value, skip it */
  338.   }
  339.  
  340.   return(TRUE);
  341. }
  342.  
  343. Boolean ReadSourceFile(asource, filename, directory)
  344. Source asource;
  345. char *filename, *directory;
  346. {
  347.   FILE *fp;
  348.   char pathname[MAX_FILENAME_LEN+1];
  349.   Boolean result;
  350.  
  351.   strncpy(pathname, directory, MAX_FILENAME_LEN);
  352.   strncat(pathname, filename, MAX_FILENAME_LEN);
  353.  
  354.   if((fp = fopen(pathname, "r")) == NULL)
  355.     return FALSE;
  356.  
  357.   asource->name = s_strdup(filename);
  358.   asource->directory = s_strdup(directory);
  359.  
  360.   result = ReadSource(asource, fp);
  361.   fclose(fp);
  362.   return(result);
  363. }
  364.  
  365. Source
  366. loadSource(name, sourcepath)
  367. char *name;
  368. char *sourcepath;
  369. {
  370.   char *i, *p, source_dir[MAX_FILENAME_LEN], sp[1000];
  371.   Source source = (Source)s_malloc(sizeof(_Source));
  372. /*
  373. #ifndef ANSI_LIKE
  374.   extern char *getenv();
  375. #endif
  376. */
  377.   if(sourcepath == NULL || sourcepath[0] == 0) {
  378.     if((sourcepath = (char*)getenv("WAISSOURCEPATH")) == NULL)
  379.       return NULL;
  380.   }
  381.  
  382.   for (p = sourcepath, i = (char*)strchr(p, ':');
  383.        i != NULL;
  384.        p = i+1) {
  385.     if((i = (char*)strchr(p, ':')) == NULL)
  386.       strcpy(source_dir, p);
  387.     else {
  388.       strncpy(source_dir, p, i-p);
  389.       source_dir[i-p] = 0;
  390.     }
  391.  
  392.     if(ReadSourceFile(source, name, source_dir)) {
  393.       set_connection(source);
  394.       Sources = makeSList(source, Sources);
  395.       return (source);
  396.     }
  397.   }
  398.   s_free(source);
  399.   source = NULL;
  400.   return (source);
  401. }
  402.  
  403. void set_connection(source)
  404. Source source;
  405. {
  406.   SList s;
  407.   for(s = Sources; s != NULL; s = s->nextSource) {
  408.     if(s->thisSource != NULL)
  409.       if (!strcmp(source->server, s->thisSource->server) &&
  410.       !strcmp(source->service, s->thisSource->service)) {
  411.     source->connection = s->thisSource->connection;
  412.     source->buffer_length = s->thisSource->buffer_length;
  413.     source->initp = s->thisSource->initp;
  414.     break;
  415.       }
  416.   }
  417. }
  418.  
  419. Boolean newSourcep(name)
  420. char *name;
  421. {
  422.   SList s;
  423.  
  424.   for (s = Sources; s != NULL; s = s->nextSource)
  425.     if((s->thisSource != NULL) &&
  426.        !strcmp(name, s->thisSource->name))
  427.       return FALSE;
  428.  
  429.   return TRUE;
  430. }
  431.  
  432. Boolean is_source(name, test)
  433. char *name;
  434. Boolean test;
  435. {
  436.   char lastchar;
  437.  
  438.   lastchar = name[strlen(name)-1];
  439.   if(test) 
  440.     return ((strlen(name) > 4) &&
  441.       strstr(name, ".src") &&
  442.       (!strcmp(".src", strstr(name, ".src"))));
  443.   else 
  444.     return (lastchar != '~' &&
  445.         lastchar != '#' &&
  446.         strcmp(name, ".") &&
  447.         strcmp(name, ".."));
  448. }
  449.  
  450. static Boolean newSource(name)
  451. char *name;
  452. {
  453.   int i;
  454.  
  455.   for(i =0; i < NumSources; i++)
  456.     if(!strcmp(name, Source_items[i]))
  457.       return FALSE;
  458.  
  459.   return TRUE;
  460. }
  461.  
  462. static int
  463. issfile(dp)
  464. struct dirent *dp;
  465. {
  466.   return(is_source(dp->d_name, TRUE) &&
  467.      newSource(dp->d_name));
  468. }
  469.  
  470. void SortSourceNames(n)
  471. int n;
  472. {
  473.   Boolean Changed = TRUE;
  474.   int i;
  475.   char *qi;
  476.  
  477.   while(Changed) {
  478.     Changed = FALSE;
  479.     for(i = 0; i < n-1; i++)
  480.       if(0 < strcasecmp(Source_items[i], Source_items[i+1])) {
  481.     Changed = TRUE;
  482.     qi = Source_items[i];
  483.     Source_items[i] = Source_items[i+1];
  484.     Source_items[i+1] = qi;
  485.       }
  486.   }
  487. }
  488.  
  489. void
  490. GetSourceNames(directory)
  491. char *directory;
  492. {
  493.   struct dirent **list;
  494.   int i, j;
  495.  
  496.   if ((j = scandir(directory, &list, issfile, alphasort)) < 0) {
  497.       PrintStatus(STATUS_INFO, STATUS_HIGH, "Error on open of source directory: %s.\n", directory);
  498.       return;
  499.     }
  500.  
  501.   if(NumSources > 0)
  502.     Source_items = (char**) s_realloc(Source_items, (NumSources+j+1) * sizeof(char*));
  503.   else {
  504.     if(Source_items != NULL) {
  505.       for (i = 0; Source_items[i] != NULL; i++) s_free(Source_items[i]);
  506.       s_free(Source_items);
  507.     }
  508.     Source_items = (char**) s_malloc((j+1) * sizeof(char*));
  509.   }
  510.  
  511.   for (i = 0; i < j; i++) {
  512.     Source_items[i+NumSources] = s_strdup(list[i]->d_name);
  513.     s_free(list[i]);
  514.   }
  515.  
  516.   NumSources+=j;
  517.   SortSourceNames(NumSources);
  518.   Source_items[NumSources] = NULL;
  519.  
  520.   s_free(list);
  521. }
  522.  
  523. /* read all the sources from a directory.  If test is true, only files ending
  524.    in .src are valid
  525.    */
  526.  
  527. void
  528. ReadSourceDirectory(directory, test)
  529. char *directory;
  530. Boolean test;
  531. {
  532.   char filename[MAX_FILENAME_LEN];
  533.   FILE *fp;
  534.   int i, j , newNumSources;
  535.   SList Last;
  536.   Source source;
  537.   struct dirent **list;
  538.  
  539.   if ((j = scandir(directory, &list, NULL, NULL)) < 0) {
  540.     return;
  541.   }
  542.  
  543.   /* find the end of the sourcelist */
  544.   if(Sources == NULL)
  545.     Sources = makeSList(NULL, NULL);
  546.  
  547.   for(Last = Sources; Last->nextSource != NULL; Last = Last->nextSource);
  548.  
  549.   for (i = 0; i < j; i++) {
  550.     if (is_source(list[i]->d_name, test)) {
  551.       if(newSourcep(list[i]->d_name)) {
  552.     strcpy(filename, directory);
  553.     strcat(filename, list[i]->d_name);
  554.     if ((fp = fopen(filename, "r")) != NULL) {
  555.       source = (Source)s_malloc(sizeof(_Source));
  556.       memset(source, 0, sizeof(_Source));
  557.       source->initp = FALSE;
  558.       source->name = s_strdup(list[i]->d_name);
  559.       source->directory = s_strdup(directory);
  560.       ReadSource(source, fp);
  561.       fclose(fp);
  562.       if(Last->thisSource == NULL)
  563.         Last->thisSource = source;
  564.       else {
  565.         Last->nextSource = makeSList(source, NULL);
  566.         Last = Last->nextSource;
  567.       }
  568.       NumSources++;
  569.     }
  570.       }
  571.     }
  572.   }
  573.   free((char *)list);
  574. }
  575.  
  576. void WriteSource(directory, source, overwrite)
  577.      char *directory;
  578.      Source source;
  579.      Boolean overwrite;
  580. {
  581.   char filename[MAX_FILENAME_LEN];
  582.   FILE *fp;
  583.   
  584.   /* build filename */
  585.   
  586.   strcpy(filename, directory);
  587.   strcat(filename, source->name);
  588.   
  589.   /* test to see if it exists */
  590.   
  591.   if (overwrite == FALSE) 
  592.     if ((fp = fopen(filename, "r")) != NULL) {
  593.       PrintStatus(STATUS_INFO, STATUS_HIGH, 
  594.           "File %s exists, click again to overwrite.\n", filename);
  595.       fclose(fp);
  596.       return;
  597.     }
  598.   
  599.   if ((fp = fopen(filename, "w")) == NULL) {
  600.     PrintStatus(STATUS_INFO, STATUS_HIGH, "Error opening %s.\n", filename);
  601.     return;
  602.   }
  603.   
  604.   fprintf(fp, "(:source\n :version 3\n");
  605.   if(source->server != NULL) 
  606.     if(source->server[0] != 0)
  607.       if(isdigit(source->server[0])) /* then it's an ip-address */
  608.     fprintf(fp, " :ip-address \"%s\"\n", source->server);
  609.       else
  610.     fprintf(fp, " :ip-name \"%s\"\n", source->server);
  611.  
  612.   if(source->service != NULL) 
  613.     if(source->service[0] != 0)
  614.       fprintf(fp, " :tcp-port %s\n", source->service);
  615.  
  616.   fprintf(fp, " :database-name \"%s\"\n", source->database);
  617.   if(source->cost != NULL) 
  618.     if(source->cost[0] != 0)
  619.       fprintf(fp, " :cost %s \n", source->cost);
  620.   else
  621.       fprintf(fp, " :cost 0.00 \n");
  622.  
  623.   if(source->units != NULL) 
  624.     if(source->units[0] != 0)
  625.       fprintf(fp, " :cost-unit %s \n", source->units);
  626.   else
  627.     fprintf(fp, " :cost-unit :free \n");
  628.   
  629.   if(source->maintainer != NULL) 
  630.     if(source->maintainer[0] != 0)
  631.       fprintf(fp, " :maintainer \"%s\"\n", 
  632.           source->maintainer);
  633.   else
  634.       fprintf(fp, " :maintainer \"%s\"\n", 
  635.           current_user_name());
  636.  
  637.   if(source->description != NULL) 
  638.     if(source->description[0] != 0) {
  639.       fprintf(fp, " :description ");
  640.       WriteString(source->description, fp);
  641.     }
  642.   else
  643.     fprintf(fp, " :description \"Created with %s by %s on %s.\"\n",
  644.         command_name, current_user_name(), printable_time());
  645.  
  646.   fprintf(fp, "\n)");
  647.   fclose(fp);
  648. }
  649.  
  650. SourceList
  651.   makeSourceList(source, rest)
  652. SourceID source;
  653. SourceList rest;
  654. {
  655.   SourceList result;
  656.   if((result = (SourceList)s_malloc(sizeof(_SourceList))) != NULL) {
  657.     result->thisSource = source;
  658.     result->nextSource = rest;
  659.   }
  660.   return(result);
  661. }
  662.  
  663. SList
  664.   makeSList(source, rest)
  665. Source source;
  666. SList rest;
  667. {
  668.   SList result;
  669.   if((result = (SList)s_malloc(sizeof(_SList))) != NULL) {
  670.     result->thisSource = source;
  671.     result->nextSource = rest;
  672.   }
  673.   return(result);
  674. }
  675.  
  676. void FreeSource(source)
  677. Source source;
  678. {
  679.   if (source != NULL) {
  680.     if(source->name != NULL)
  681.       s_free (source->name);
  682.     if(source->directory != NULL)
  683.       s_free (source->directory);
  684.     if(source->description != NULL)
  685.       s_free (source->description);
  686.     if(source->maintainer != NULL)
  687.       s_free (source->maintainer);
  688.     s_free(source);
  689.   }
  690. }
  691.  
  692. void FreeSources(sources)
  693. SList sources;
  694. {
  695.  SList s, n;
  696.  
  697.  for (s = sources; s != NULL; s = n) {
  698.    n = s->nextSource;
  699.    FreeSource(s->thisSource);
  700.    s_free(s);
  701.  }
  702.  
  703.  NumSources = 0;
  704.  sources = NULL;
  705. }
  706.  
  707. Source
  708.   findsource(name, sourcepath)
  709. char* name;
  710. char* sourcepath;
  711. {
  712.   SList asource;
  713.  
  714.   for(asource = Sources; 
  715.       asource != NULL;
  716.       asource = asource->nextSource) {
  717.     if (!strcmp(name, asource->thisSource->name)) {
  718.       return asource->thisSource;
  719.     }
  720.   }
  721.   return (loadSource(name, sourcepath));
  722. }
  723.  
  724. Source
  725.   findSource(n)
  726. int n;
  727. {
  728.   SList asource;
  729.  
  730.   for(asource = Sources; 
  731.       (n > 0) && (asource != NULL);
  732.       asource = asource->nextSource, n--);
  733.  
  734.   if (asource != NULL) return asource->thisSource;
  735.   else return NULL;
  736. }
  737.  
  738. void
  739. format_source_cost(str,source)
  740. char *str;
  741. Source source;
  742. {
  743.   sprintf(str,"Free");
  744.   if ((source->units != NULL) && (source->cost != NULL)) {
  745.      
  746.      if(0 == strcmp(source->units, ":dollars-per-query"))
  747.         sprintf(str,"$%s/query",source->cost);
  748.  
  749.      if(0 == strcmp(source->units, ":dollars-per-minute"))
  750.         sprintf(str,"$%s/minute",source->cost);
  751.  
  752.      if(0 == strcmp(source->units, ":dollars-per-retrieval"))
  753.         sprintf(str,"$%s/retrieval",source->cost);
  754.  
  755.      if(0 == strcmp(source->units, ":dollars-per-session"))
  756.         sprintf(str,"$%s/session",source->cost);
  757.  
  758.      if(0 == strcmp(source->units, ":other"))
  759.         sprintf(str,"Special",source->cost);
  760.   }
  761. }
  762.  
  763. void
  764. freeSourceList(slist)
  765. SourceList slist;
  766. {
  767.   SourceList sl;
  768.   while(slist != NULL) {
  769.     sl = slist;
  770.     freeSourceID(sl->thisSource);
  771.     slist = sl->nextSource;
  772.     s_free(sl);
  773.   }
  774. }
  775.  
  776. #include <sockets.h>
  777.  
  778. /* #define FORWARDER_SERVER "welchlab.welch.jhu.edu" */
  779.  
  780. Boolean init_for_source(source, request, length, response)
  781. Source source;
  782. char *request;
  783. long length;
  784. char *response;
  785. /* send an init message to the source.  A side effect is that the 
  786.    negotiation of buffer sizes.  The final size is put in 
  787.    source->buffer_length 
  788.  */
  789. {
  790.   char userInfo[500];
  791.   char message[500];
  792.   char hostname[80];
  793. /*  char domain[80]; */
  794.   char *domain;
  795.   struct hostent *my_host_ent;
  796.  
  797.   mygethostname(hostname, 80);
  798. /* Security patch from mike@tab00.larc.nasa.gov */
  799.   if (((my_host_ent = gethostbyname(hostname)) == NULL) ||
  800.       (domain = (char *)index(my_host_ent->h_name, '.')) == NULL)
  801.     domain = "unknown";
  802.   else
  803.     domain++;
  804.  
  805. /*  getdomainname(domain, 80); */
  806.  
  807. #ifdef TELL_USER
  808.   {
  809.   char *env_user;
  810.   if (!(env_user = getenv("USER")))
  811.     env_user = "nobody";  
  812.   sprintf(userInfo, "%s %s, from host: %s.%s, user: %s",
  813.       command_name, VERSION, hostname, domain, env_user);
  814.   }
  815. #else
  816.   sprintf(userInfo, "%s %s, from host: %s.%s",
  817.       command_name, VERSION, hostname, domain);
  818. #endif
  819.  
  820.   if(source->initp == FALSE) {
  821.     if(source->server[0] == 0)
  822.       source->connection = NULL;
  823.     else {
  824.       source->connection = connect_to_server(source->server,
  825.                          atoi(source->service));
  826. #ifdef FORWARDER_SERVER
  827.  
  828. #ifndef FORWARDER_SERVICE
  829. #define FORWARDER_SERVICE "210"
  830. #endif
  831.  
  832.       if(source->connection == NULL) {
  833.     strncat(source->database, "@", STRINGSIZE);
  834.     strncat(source->database, source->server, STRINGSIZE);
  835.     strncat(source->database, ":", STRINGSIZE);
  836.     strncat(source->database, source->service, STRINGSIZE);
  837.     strncpy(source->server, FORWARDER_SERVER, STRINGSIZE);
  838.     strncpy(source->service, FORWARDER_SERVICE, STRINGSIZE);
  839.     source->connection = connect_to_server(source->server,
  840.                            atoi(source->service));
  841.       }
  842. #endif
  843.  
  844.       if (source->connection == NULL) {
  845.     PrintStatus(STATUS_URGENT, STATUS_HIGH, "Bad Connection to server.");
  846.     source->initp = FALSE;
  847.     return source->initp;
  848.       }
  849.     }
  850.     source->buffer_length = 
  851.       init_connection(request, response,
  852.               length,
  853.               source->connection,
  854.               userInfo);
  855.  
  856.     if (source->buffer_length < 0) {
  857.       PrintStatus(STATUS_URGENT, STATUS_HIGH,
  858.           "\nError connecting to server: %s service: %s.",
  859.           source->server, source->service);
  860.       source->initp = FALSE;
  861.     }
  862.     else {
  863.       SList s;
  864.  
  865.       source->initp = TRUE;
  866.       /* set the init and connection for other sources with the same
  867.      host and port. */
  868.       for (s = Sources; s != NULL; s = s->nextSource) {
  869.           if (s->thisSource != source) {
  870.       if (strcmp(s->thisSource->server, source->server) == 0 &&
  871.           strcmp(s->thisSource->service, source->service) == 0) {
  872.         s->thisSource->connection = source->connection;
  873.         s->thisSource->buffer_length = source->buffer_length;
  874.         s->thisSource->initp = TRUE;
  875.       }
  876.     }
  877.       }
  878.     }
  879.     return source->initp;
  880.   }
  881.   return source->initp;
  882. }
  883.